package com.jt.service;/**
 * @Author 金帮嘉诚 @Date 2021-08-06 星期五 9:42
 */
/*本类用于测试*/

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jt.mapper.ItemCatMapper;
import com.jt.pojo.ItemCat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 知识点
 * 商品分类业务
 */
@Service
public class ItemCatServiceImpl implements ItemCatService {
    @Autowired
    private ItemCatMapper itemCatMapper;

    /**
     * 查询3级商品分类信息
     * 1.
     * 2.
     * 1.0版本 for循环嵌套 好理解
     * 常识:
     * 1.用户第一次查询数据库 需要建立动态链接
     * 2.用户第二次查询 从连接池中动态获取连接 所以速度更快
     *
     * @param level 1只查询1级商品分类 2查询1级和2级 3查询1\2\3级
     * @return 思考:该业务查询了多少次数据库???例如第一层循环10个 第二层循环10个 共查100次
     * 优化策略??
     */
    @Override
    //设计:Map<> key:父id value:对应子菜单List
    //只查询一次 然后获得父id和子链表的对应关系 依此来获取最终的菜单
    public List<ItemCat> findItemCatList(Integer level) {
        Map<Integer, List<ItemCat>> map = getItemCatMap();
        if (level == 1) {//只获取1级菜单 parent_id=0
            return map.get(0);
        }
        if (level == 2) {
            return getLevel2List(map);
        }
//        if (level == 3) {//由于只有3级 不用写判断
        return getLevel3List(map);
//        }
    }

    /**
     * 查询1级和2级菜单信息
     */
    public List<ItemCat> getLevel2List(Map<Integer, List<ItemCat>> map) {
        //思路:先查询1级,之后循环遍历 再次封装2级
        //1.获取1级
        List<ItemCat> oneList = map.get(0);
        for (ItemCat oneItemCat : oneList
        ) {
            //根据1级查2级:1.获取对应2级菜单 2.放入children
//            map.get("1级的id");
            List<ItemCat> twoList = map.get(oneItemCat.getId());
            oneItemCat.setChildren(twoList);
        }
        return oneList;
    }

    /**
     * 查询1\2\3级菜单信息
     */
    public List<ItemCat> getLevel3List(Map<Integer, List<ItemCat>> map) {
        List<ItemCat> oneList = getLevel2List(map);
        for (ItemCat oneItemCat : oneList
        ) {
            List<ItemCat> twoList = oneItemCat.getChildren();
            //一定先判断是否为空 再判断长度 不然报空指针错
            if (twoList == null || twoList.size() == 0) {
                continue;
            }
            for (ItemCat twoItemCat : twoList
            ) {
                List<ItemCat> threeList = map.get(twoItemCat.getId());
                twoItemCat.setChildren(threeList);
            }
        }
        return oneList;
    }

    /**
     * 将所有父子关系封装到Map
     */
    public Map<Integer, List<ItemCat>> getItemCatMap() {
        //将会包含所有父子关系
        Map<Integer, List<ItemCat>> map = new HashMap<>();
        //获取所有记录
        List<ItemCat> itemCatList = itemCatMapper.selectList(null);
        //实现关系封装
        for (ItemCat i : itemCatList
        ) {
            /**
             * 1.key无对应值 创建list追加i 加入map的value
             * 2.key中有对应值 获取对应list 追加i
             * */
            int key = i.getParentId();
            List<ItemCat> list = new ArrayList<>();

            if (map.containsKey(key)) {//有对应值时
                list = map.get(key);//只需add 不需put 操作的是对象的引用
            }
            list.add(i);
            map.put(key, list);
        }
        //实现数据关系封装 老师的写法
//        for(ItemCat i:itemCatList){
//           int key = i.getParentId();
//           if(map.containsKey(key)){//存在
//               List<ItemCat> list=map.get(key);
//               //将自己追加到其中
//               list.add(i);
//           }else {//不存在 准备list集合 将自己作为第一个元素封装
//               List<ItemCat> list=new ArrayList<>();
//               list.add(i);
//               map.put(key,list);
//           }
//        }
        return map;
    }
    //只查询一次 然后遍历获得的List
    //测试调用 网页调用
    //1746    140
    //2109    109
    //2593    64
    //1869    129
    //1693    120
    //        65
//    @Override//设想:只查询一次
//    public List<ItemCat> findItemCatList(Integer level) {
//        List<ItemCat> allList0 = itemCatMapper.selectList(null);
//        //使用CopyOneWriteArrayList 在remove时不会产生ConcurrentModificationException错误,
//        // 因为一般List在remove后元素位置会改变,这导致遍历List时会出问题
//        List<ItemCat> allList = new CopyOnWriteArrayList<>(allList0);
//        List<ItemCat> oneList = new ArrayList<>();
//        List<ItemCat> twoList = new ArrayList<>();
//        List<ItemCat> threeList = new ArrayList<>();
//        //获取allList中 父id为0的 放进oneList 并从allList中移除
//        for (ItemCat i : allList
//        ) {
//            if (i.getParentId() == 0) {
//                oneList.add(i);
//                allList.remove(i);
//            }
//        }
//
//        //获取allList中 父id为    的 放进twoList 并从allList中移除
//        for (ItemCat i1 : oneList) {
//            for (ItemCat i : allList
//            ) {
//                if (i.getParentId().equals(i1.getId())) {
//                    twoList.add(i);
//                    allList.remove(i);
//                }
//            }
//            //必须深拷贝 不然清空时会出问题
//            //深拷贝的其中一种方式 先创建一个和twoList相同大小或更大的List 再调用Collections.copy方法 两步都是必须的
//            List<ItemCat> copyList = new ArrayList<>(Arrays.asList(new ItemCat[twoList.size()]));
//            Collections.copy(copyList, twoList);
//            i1.setChildren(copyList);
//            twoList.clear();
//        }
//        //获取allList中 父id为  的 放进threeList 并从allList中移除
//        for (ItemCat i1 : oneList
//        ) {
//            for (ItemCat i2 : i1.getChildren()
//            ) {
//                for (ItemCat i : allList
//                ) {
//                    if (i.getParentId().equals(i2.getId())) {
//                        threeList.add(i);
//                        allList.remove(i);
//                    }
//                }
//                List<ItemCat> copyList = new ArrayList<>(Arrays.asList(new ItemCat[threeList.size()]));
//                Collections.copy(copyList, threeList);
//                i2.setChildren(copyList);
//                threeList.clear();
//            }
//        }
//
//
//        return oneList;
//    }

    //下面是两种循环遍历实现
    //测试调用 网页调用
    // 4025     962
    // 3599     793
    // 2568     1313
    // 7788     980
    // 3696     957
    // 4402     919
    // 4321     1207
//    @Override
//    public List<ItemCat> findItemCatList(Integer level) {
//        //1.查询一级商品分类信息
//        QueryWrapper<ItemCat> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("parent_id", 0);
//        List<ItemCat> oneList = itemCatMapper.selectList(queryWrapper);
//
//        //2.查询二级商品信息 遍历一遍集合
//        for (ItemCat i : oneList
//        ) {
//            queryWrapper.clear();
//            queryWrapper.eq("parent_id", i.getId());
//            List<ItemCat> twoList = itemCatMapper.selectList(queryWrapper);
//            //3.将二级封装给一级
//            i.setChildren(twoList);
//            //
//            for (ItemCat i2 : twoList
//            ) {
//                queryWrapper.clear();
//                queryWrapper.eq("parent_id", i2.getId());
//                List<ItemCat> threeList = itemCatMapper.selectList(queryWrapper);
//                i2.setChildren(threeList);
//            }
//        }
//        return oneList;
//    }
    //测试调用 网页调用
    //3527    1057
    //2532    1092
    //3742    1133
//    @Override
//    public List<ItemCat> findItemCatList(Integer level) {
//        QueryWrapper<ItemCat> queryWrapper = new QueryWrapper<>();
//        //获得一级菜单信息
//        List<ItemCat> itemCatList = new ArrayList<>();
//        queryWrapper.eq("parent_id", 0);
//        itemCatList = itemCatMapper.selectList(queryWrapper);
//        //二级菜单
//        //遍历得到每个项目的children 并放入该列
//        for (ItemCat i1 : itemCatList
//        ) {
//            queryWrapper.clear();
//            queryWrapper.eq("parent_id", i1.getId());
//            List<ItemCat> childrenItemCatList = itemCatMapper.selectList(queryWrapper);
//            i1.setChildren(childrenItemCatList);
//        }
//
//        //三级菜单
//        for (ItemCat i1 : itemCatList
//        ) {
//            for (ItemCat i2 : i1.getChildren()
//            ) {
//                queryWrapper.clear();
//                queryWrapper.eq("parent_id", i2.getId());
//                List<ItemCat> childrenItemCatList = itemCatMapper.selectList(queryWrapper);
//                i2.setChildren(childrenItemCatList);
//            }
//        }
//        return itemCatList;
//    }
    //sql语句递归 最慢
    //测试调用 网页调用
    //8320   3522
    //8521   5147
    //8852   5085
//    @Override
//    public List<ItemCat> findItemCatList(Integer level) {
//        List<ItemCat> catList = itemCatMapper.findItemCatList(level);
//        return catList;
//    }

    /**
     * 修改商品分类状态
     * 参数 id status
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer updateStatus(ItemCat itemCat) {
        ItemCat itemCat1 = itemCatMapper.selectById(itemCat);
        itemCat1.setStatus(itemCat.getStatus());
        return itemCatMapper.updateById(itemCat1);
    }

    /**
     * 新增 商品分类
     * 传入了 分类名 父id level
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer saveItemCat(ItemCat itemCat) {
        return itemCatMapper.insert(itemCat);
    }

    /**
     * 修改 商品分类 传入了整个对象
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer updateItemCat(ItemCat itemCat) {
        return itemCatMapper.updateById(itemCat);
    }

    /**
     * 删除 商品分类
     * 要求删除指定商品分类 以及所有子孙分类
     * 为了性能 不要查询太多次
     */
    @Override
    @Transactional(rollbackFor = Exception.class)//不要忘记事务控制
    public Integer deleteItemCat(Integer id, Integer level) {//比较直观
        List<Integer> ids = new ArrayList<>();
        ids.add(id);

        if (level.equals(1)) {
            return delLevel1(ids);
        }
        if (level.equals(2)) {
            return delLevel2(ids);
        }
        //level为3时
        return itemCatMapper.deleteById(id);
    }

    //获取下级id集合
    private List<Integer> getNextLevel(List<Integer> ids) {
        //当输入为空时退出
        if (ids == null || ids.size() == 0) {
            return new ArrayList<>();
        }
        QueryWrapper<ItemCat> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("parent_id", ids);
        List<ItemCat> itemCatList = itemCatMapper.selectList(queryWrapper);

        List<Integer> integers = new ArrayList<>();
        for (ItemCat i : itemCatList
        ) {
            integers.add(i.getId());
        }
        return integers;
    }

    //根据输入的某级的id集合 删除对应下一级id的List集合
    private Integer delNextLevel(List<Integer> ids) {
        //输入为空时退出
        if (ids == null || ids.size() == 0) {
            return 0;
        }
        List<Integer> nextLevel = getNextLevel(ids);
        //输入为空时退出
        if (nextLevel.size() == 0) {
            return 0;
        }
        return itemCatMapper.deleteBatchIds(nextLevel);
    }

    //从2级开始删除对应项
    //参数为2级菜单列表
    private Integer delLevel2(List<Integer> ids2) {
        //输入为空时退出
        if (ids2 == null || ids2.size() == 0) {
            return 0;
        }
        //删除2级3级
        return delNextLevel(ids2) + itemCatMapper.deleteBatchIds(ids2);
    }

    //从1级开始删除对应项
    //参数为1级菜单列表
    private Integer delLevel1(List<Integer> ids1) {
        //输入为空时退出
        if (ids1 == null || ids1.size() == 0) {
            return 0;
        }
        List<Integer> id2List = getNextLevel(ids1);
        //输入为空时退出
        if (id2List.size() == 0) {
            return itemCatMapper.deleteBatchIds(ids1);
        }
        //删除
        return delLevel2(id2List) + itemCatMapper.deleteBatchIds(ids1);
    }
}
